import { EnumBjlResult } from "@/models/enums/EnumBjlResult";
import { RoundInfo, RecmInfo, ExcutePlan } from "../ExecutePlan";
import { IRecmStrategy } from "../IRecmStrategy";
import { IPlan } from "../IExecutePlan";
import { FollowFixedResultStrategy, FollowStrategy } from "./FollowStrategy";

export class ArrayPointer {
    protected _row: number = -1;
    public get row() {
        return this._row;
    }
    public set row(value: number) {
        this._row = value;
    }
    protected _col: number = -1;
    public get col() {
        return this._col;
    }
    public set col(value: number) {
        this._col = value;
    }
    constructor(row: number, col: number) {
        this._col = col;
        this._row = row;
    }
}

export class DynamicFollowStrategy implements IRecmStrategy {
    strategyName: string = "";
    debugCompoenent: string = "DynamicFollowStrategyDebug";
    protected _subPlan: IPlan[][] = [];
    public get subPlan() {
        return this._subPlan;
    }

    protected _selectPointer: ArrayPointer[] = [];

    public get selectPointer() {
        return this._selectPointer;
    }

    // protected _selectRow: number = -1;
    // public get selectRow() {
    //     return this._selectRow;
    // }

    // protected _selectColumn: number = -1;;
    // public get selectColumn() {
    //     return this._selectColumn;
    // }
    protected _maxRow: number = 1000;
    protected _maxCol: number = 100;
    constructor(name: string, maxRow: number, maxCol: number) {
        this.strategyName = name;
        this._maxRow = maxRow;
        this._maxCol = maxCol;
        this.resetRecm();
    }
    setResult(roundInfo: RoundInfo, recmInfo: RecmInfo, multiple: number, waterRate: number, fuliRate: number): void {
        // pl.setResult(roundInfo, pl.recmInfo, pl.multiple, pl.waterRate, pl.fuliRate)
        this._subPlan.forEach(gt => gt.forEach(pl => pl.setResult(roundInfo, pl.recmInfo, pl.multiple, pl.waterRate, pl.fuliRate)));

        let round = roundInfo.results.length;

        for (let i = 0; i < this._subPlan.length; i++) {
            if (this._subPlan[i].length <= this._maxCol) {
                let luckPlan = new ExcutePlan();
                luckPlan.planName = `运势${i + 1}.${this._subPlan[i].length}`;
                luckPlan.recmStrategy = [new FollowFixedResultStrategy((i + 1), (this._subPlan[i].length))]
                this._subPlan[i].push(luckPlan);
            }
        }

        if (this._subPlan.length <= this._maxRow) {
            let followArray: IPlan[] = [];
            let followCount = round;
            let followPlan = new ExcutePlan();
            followPlan.planName = "跟投" + followCount;
            followPlan.recmStrategy = [new FollowStrategy({ followCount: followCount, reverse: false })]
            followArray.push(followPlan);
            this._subPlan.push(followArray);
        }

    }
    toResult(roundInfo: RoundInfo): EnumBjlResult {
        let maxLFwin = 0;
        let selectPointer: ArrayPointer[] = [];
        this._subPlan.forEach((gt, row) => gt.forEach((pl, col) => {

            let plRecmV = pl.toResult(roundInfo);
            pl.userRecmInfo.recmV = plRecmV;
            pl.recmInfo.recmV = plRecmV;
            if (pl.userRecmInfo.summaryInfo.lfail > 0 && pl.userRecmInfo.recmV != EnumBjlResult.U) {
                pl.recmInfo.recmV = pl.userRecmInfo.recmV == EnumBjlResult.Z ? EnumBjlResult.X : EnumBjlResult.Z;
            }
            let lfwin = pl.userRecmInfo.summaryInfo.lwin > pl.userRecmInfo.summaryInfo.lfail
                ? pl.userRecmInfo.summaryInfo.lwin : pl.userRecmInfo.summaryInfo.lfail;
            if (lfwin > maxLFwin && lfwin > 0) {
                maxLFwin = lfwin;
                selectPointer = [new ArrayPointer(row, col)];
            }
            else if (lfwin == maxLFwin && lfwin > 0) {
                selectPointer.push(new ArrayPointer(row, col));
            }

        }));

        let recmV = EnumBjlResult.U;

        this._selectPointer = selectPointer;

        let iv = 0;
        if (this._subPlan.length >= this._maxRow && this._subPlan[this.subPlan.length - 1].length >= this._maxCol) {
            this._selectPointer.forEach(point => {
                let rv = this._subPlan[point.row][point.col].recmInfo.recmV;
                if (rv == EnumBjlResult.Z) {
                    iv++;
                }
                else if (rv == EnumBjlResult.X) {
                    iv--;
                }
            })
            if (iv > 0) {
                recmV = EnumBjlResult.Z;
            }
            else if (iv < 0) {
                recmV = EnumBjlResult.X;
            }
            else {
                recmV = EnumBjlResult.U;
            }
        }


        return recmV;
    }
    resetRecm(): void {
        this._selectPointer = [];
        this._subPlan.splice(0, this._subPlan.length);
    }
    copyValue(valueObj: any): void {
        var obj = valueObj as DynamicFollowStrategy;
        if (obj) {
            this._selectPointer = obj._selectPointer;
            this._maxCol = obj._maxCol;
            this._maxRow = obj._maxRow;
            this._subPlan.splice(0, this._subPlan.length);
            for (let i = 0; i < obj._subPlan.length; i++) {
                let itemArray: IPlan[] = [];
                for (let j = 0; j < obj._subPlan[i].length; j++) {
                    let plan: IPlan;
                    if (j == 0) {
                        plan = new ExcutePlan();
                        plan.recmStrategy = [new FollowStrategy()];
                        plan.copyValue(obj._subPlan[i][0]);
                    }
                    else {
                        plan = new ExcutePlan();
                        plan.recmStrategy = [new FollowFixedResultStrategy()];
                        plan.copyValue(obj._subPlan[i][j]);
                    }
                    itemArray.push(plan);
                }
                this._subPlan.push(itemArray);
            }
        }
    }

}